package com.yixiu.demo.bio.registerserver;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Method;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;



public class RpcServesFactoryImpl implements IRpcServerFactory {
    private int port;
    // 保存服务名和具体实现类
    public static final HashMap<String, Class> serviceRegistry = new HashMap<String, Class>();
    // 使用线程池处理客户端请求
    private static final ThreadPoolExecutor executor = new ThreadPoolExecutor(20, 20, 100, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(100));

    //服务端构造函数只需要一个端口号
    public RpcServesFactoryImpl(int port) {
        this.port = port;
    }

    /**
     * 启动服务
     */
    @Override
    public void start() throws IOException {
        // socket绑定端口
        ServerSocket server = new ServerSocket();
        server.bind(new InetSocketAddress(port));
        System.out.println("Bio rpc 服务启动开始###端口###" + port);
        try {
            while (true) {
                System.out.println("等待客户端接入");
                // 阻塞模式，只要有客户端请求过来，就开启一个线程处理
                executor.execute(new ServersTask(server.accept()));
            }
        } catch (Exception e) {
            if (server != null) {
                server.close();
            }
        }
    }

    // 注册服务：将服务名和具体实现类放入hashmap
    @Override
    public void register(Class serviceInterface, Class impl) {
        serviceRegistry.put(serviceInterface.getName(), impl);
    }

    //内部静态类实现   线程处理
    static class ServersTask implements Runnable {
        Socket client = null;

        // 使用服务端 收到的socket构造线程类
        public ServersTask(Socket socket) {
            this.client = socket;
        }

        // bio的实现方式：阻塞，效率较低
        ObjectInputStream input = null;//输入流
        ObjectOutputStream output = null;//输出流

        @Override
        public void run() {
            //接收客户端发送来的字节流,并转化成对象,反射调用服务实现者,获取执行结果
            try {
                input = new ObjectInputStream(this.client.getInputStream());
                String interfaceName = input.readUTF();  // 读取接口名
                String methodName = input.readUTF(); // 读取方法名
                Class<?>[] parameterType = (Class<?>[]) input.readObject(); // 读取参数类型
                Object[] args = (Object[]) input.readObject(); // 读取参数
                Class serverClass = serviceRegistry.get(interfaceName); // 根据服务名查找 具体实现类
                if (serverClass == null) {
                    throw new ClassNotFoundException(interfaceName + " not found");
                }
                Method method = serverClass.getMethod(methodName, parameterType);  // 通过反射，获取方法
                Object result = method.invoke(serverClass.newInstance(), args); // 通过反射调用方法，获取结果
                //执行结果反序列化返回给客户端
                output = new ObjectOutputStream(this.client.getOutputStream()); // 从socket获取输出流
                output.writeObject(result);  // 将结果写到输出流
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (output != null) {
                    try {
                        output.close(); // 关闭输出流
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (input != null) {
                    try {
                        input.close();  // 关闭输入流
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (this.client != null) {
                    try {
                        this.client.close(); // 关闭socket
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }

        }
    }





}
